import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from ttkbootstrap.dialogs.dialogs import Messagebox
from ttkbootstrap.scrolled import ScrolledText
from socket import *
from create_sign import *
import ast
import time
import pymysql


class ClientPage:
    def __init__(self, master=None, server=None):
        self.root = master
        self.server = server
        self.root.minsize(800, 650)
        self.d2 = ttk.StringVar()
        self.P = ttk.StringVar()
        self.username = ttk.StringVar()
        self.password = ttk.StringVar()
        self.message_box_ScrolledText = None
        self.server_socket = None
        self.message = None
        self.verify_page()

    def verify_page(self):

        title_label = ttk.Label(self.root, text="协同签名服务器状态信息", font=("楷体", 20))
        title_label.pack(side=TOP, padx=20, pady=5)

        message_box_labelframe = ttk.Labelframe(self.root, text="交互信息")
        self.message_box_ScrolledText = ScrolledText(message_box_labelframe, height=18, autohide=True)
        self.message_box_ScrolledText.pack(fill=X, side=TOP, padx=5, pady=5)
        message_box_labelframe.pack(fill=X, side=TOP, padx=20)

        private_key_labelframe = ttk.Labelframe(self.root, text="服务器端协同签名子私钥")
        private_key_label = ttk.Label(private_key_labelframe, textvariable=self.d2, wraplength=750)
        private_key_label.pack(fill=X, padx=2)
        private_key_labelframe.pack(side=TOP, fill=X, padx=20, pady=5)

        public_key_labelframe = ttk.Labelframe(self.root, text="服务器端协同签名公钥")
        public_key_label = ttk.Label(public_key_labelframe, textvariable=self.P, wraplength=750)
        public_key_label.pack(fill=X, padx=2)
        public_key_labelframe.pack(side=TOP, fill=X, padx=20, pady=5)

        control_button_frame_1 = ttk.Frame(self.root)
        start_button = ttk.Button(control_button_frame_1, text="开启服务",
                                  command=self.connect)
        start_button.pack(side=LEFT, padx=50, pady=5, fill=X, expand=YES)
        start_button = ttk.Button(control_button_frame_1, text="添加用户", command=self.add_user)
        start_button.pack(side=LEFT, padx=50, pady=5, fill=X, expand=YES)
        control_button_frame_1.pack(fill=X, padx=20, pady=5, side=TOP)

    def add_user(self):
        top1 = ttk.Toplevel("添加用户")
        top1.geometry("600x450+150+150")
        top1.minsize(600, 450)
        username_labelframe = ttk.Labelframe(top1, text="用户名", width=50)
        username_entry = ttk.Entry(username_labelframe, textvariable=self.username, style="light")
        username_entry.pack(fill=X, padx=2)
        username_labelframe.pack(side=TOP, fill=X, padx=20, pady=(120, 5))

        password_labelframe = ttk.Labelframe(top1, text="密码")
        password_entry = ttk.Entry(password_labelframe, textvariable=self.password, style="light")
        password_entry.pack(fill=X, padx=2)
        password_labelframe.pack(side=TOP, fill=X, padx=20, pady=5)

        submit_button = ttk.Button(top1, text="添加用户", command=self.connect_mysql)
        submit_button.pack(side=TOP, padx=10, pady=5)
        top1.mainloop()

    def connect_mysql(self):
        conn = pymysql.connect(
            host='bj-cynosdbmysql-grp-by5kvszc.sql.tencentcdb.com',  # 我的IP地址
            port=25565,  # 不是字符串不需要加引号。
            user='root',
            password='iphone4S.',
            db='Cooperative_signature',
            charset='utf8'
        )
        cursor = conn.cursor()
        usern = self.server.message_to_sm3_hash([self.username.get()])
        passw = self.server.message_to_sm3_hash([self.password.get()])
        sql = 'insert into admin (username, password) values ("%s", "%s")' % (usern, passw);
        print(sql)
        res = cursor.execute(sql)
        print(res)
        conn.commit()
        cursor.close()
        conn.close()
        if res:
            Messagebox.ok(title='添加用户', message='新用户添加成功!')
            print('用户添加成功')
        else:
            # self.response = False
            Messagebox.show_warning(title='添加用户', message='新用户添加失败!')
            print('用户添加失败')

    def connect(self):
        # 使用IPV4和TCP协议
        tcp_server = socket(AF_INET, SOCK_STREAM)
        # 设定ip和端口
        IP_PORT = ('', 8000)
        # 绑定链接
        tcp_server.bind(IP_PORT)
        # 设置客户端最大链接数目
        tcp_server.listen(5)
        # 允许进行连接 返回元组 参数1是返回的内容 参数2是客户端返回的地址和端口
        self.server_socket, clientAddr = tcp_server.accept()

        t = time.gmtime()
        temp2 = (time.strftime("%Y-%m-%d %H:%M:%S", t))
        self.message_box_ScrolledText.insert(END, temp2 + "\n")
        self.message_box_ScrolledText.insert(END, f"签名客户端{clientAddr}已连接协同签名服务器" + "\n")
        self.message_box_ScrolledText.insert(END, "\n")
        self.create_key_sign(self.server, server_socket=self.server_socket)

    def server_inter(self, typeid, server_socket, send_data="默认"):  # 当typeid的值为0时执行发送程序 当typeid值为1时执行接收程序
        if typeid == 0:
            while True:
                server_socket.send(send_data.encode("gbk"))
                from_server_msg = server_socket.recv(1024)
                if from_server_msg:
                    print(from_server_msg.decode("gbk"))
                    break
        elif typeid == 1:
            while True:
                flag = "server已收到消息"
                from_client_msg = server_socket.recv(1024)
                if len(from_client_msg) != 0:
                    temp1 = "sever收到的消息是:" + from_client_msg.decode("gbk")
                    # print()
                    t = time.gmtime()
                    temp2 = (time.strftime("%Y-%m-%d %H:%M:%S", t))
                    self.message_box_ScrolledText.insert(END, temp2 + "\n")
                    self.message_box_ScrolledText.insert(END, temp1 + "\n")
                    self.message_box_ScrolledText.insert(END, "\n")
                    self.server_socket.send(flag.encode("gbk"))
                    print(temp1)
                    return from_client_msg.decode("gbk")

    def create_key_sign(self, server, server_socket):
        self.message = ast.literal_eval(self.server_inter(typeid=1, server_socket=server_socket))  # 接收数据0
        server.server_out_d2p2()
        self.d2.set(self.server.d2)
        self.server_inter(typeid=0, server_socket=server_socket, send_data=str(server.p2))  # 发送数据1
        p1 = self.server_inter(typeid=1, server_socket=server_socket)  # 接收数据2
        server.server_out_P2(p1=p1)
        self.P.set(self.server.P2)

        server.message_to_sm3_hash(self.message)
        Q1 = self.server_inter(typeid=1, server_socket=server_socket)  # 接收数据3
        server.server_out_k2Q2()
        self.server_inter(typeid=0, server_socket=server_socket, send_data=str(server.Q2))  # 发送数据4
        server.server_out_r2c1c1(Q1=Q1)
        self.server_inter(typeid=0, server_socket=server_socket, send_data=str(server.c1))  # 发送数据5
        s1 = int(self.server_inter(typeid=1, server_socket=server_socket))  # 接收数据6
        server.server_out_s2(s1=s1)
        self.server_inter(typeid=0, server_socket=server_socket, send_data=str(server.s2))  # 发送数据7
        self.server_inter(typeid=0, server_socket=server_socket, send_data=str(server.c2))  # 发送数据8


if __name__ == '__main__':
    server = CryptSM2()

    root = ttk.Window("协同签名服务端", "cosmo")
    ClientPage(root, server)
    root.mainloop()
